<!DOCTYPE html>
<html>
<head>
<title>p-V Diagram</title>
</head>
<body>
<canvas id="thermo-diagram" width="500" height="420"></canvas>
<script>
    const canvas = document.getElementById('thermo-diagram');
    const ctx = canvas.getContext('2d');

    // Style settings
    ctx.strokeStyle = 'black';
    ctx.fillStyle = 'black';
    ctx.lineWidth = 2;
    ctx.font = 'italic 24px serif';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';

    // A custom function to draw the filled triangular arrowheads seen in the image.
    function drawArrowhead(x, y, angle, size) {
        ctx.save();
        ctx.translate(x, y);
        ctx.rotate(angle);
        ctx.beginPath();
        ctx.moveTo(0, 0);
        ctx.lineTo(-size, -size / 2.5);
        ctx.lineTo(-size, size / 2.5);
        ctx.closePath();
        ctx.fill();
        ctx.restore();
    }

    // Define coordinates for the axes and origin
    const origin = { x: 60, y: 380 };
    const pAxis = { x: origin.x, y: 40 };
    const vAxis = { x: 460, y: origin.y };

    // Draw p-axis (vertical)
    ctx.beginPath();
    ctx.moveTo(origin.x, origin.y);
    ctx.lineTo(pAxis.x, pAxis.y);
    ctx.stroke();
    // Arrowhead for p-axis
    ctx.beginPath();
    ctx.moveTo(pAxis.x, pAxis.y);
    ctx.lineTo(pAxis.x - 6, pAxis.y + 12);
    ctx.moveTo(pAxis.x, pAxis.y);
    ctx.lineTo(pAxis.x + 6, pAxis.y + 12);
    ctx.stroke();
    ctx.fillText('p', pAxis.x + 25, pAxis.y + 10);

    // Draw V-axis (horizontal)
    ctx.beginPath();
    ctx.moveTo(origin.x, origin.y);
    ctx.lineTo(vAxis.x, vAxis.y);
    ctx.stroke();
    // Arrowhead for V-axis
    ctx.beginPath();
    ctx.moveTo(vAxis.x, vAxis.y);
    ctx.lineTo(vAxis.x - 12, vAxis.y - 6);
    ctx.moveTo(vAxis.x, vAxis.y);
    ctx.lineTo(vAxis.x - 12, vAxis.y + 6);
    ctx.stroke();
    ctx.fillText('V', vAxis.x + 15, vAxis.y + 5);

    // Label Origin
    ctx.fillText('O', origin.x - 20, origin.y + 15);

    // --- Top Curve (Process B -> A) ---
    // Point A has lower volume and higher pressure than point B.
    const pointA = { x: 120, y: 120 };
    const pointB = { x: 280, y: 160 };
    // A control point is used to create the concave-up curve shape.
    // It's placed "above" the midpoint of the line segment AB to make the curve bend away from the origin.
    const controlPoint1 = {
        x: (pointA.x + pointB.x) / 2,
        y: (pointA.y + pointB.y) / 2 - 25
    };

    // Draw the curve path using a quadratic Bezier curve
    ctx.beginPath();
    ctx.moveTo(pointA.x, pointA.y);
    ctx.quadraticCurveTo(controlPoint1.x, controlPoint1.y, pointB.x, pointB.y);
    ctx.stroke();

    // Calculate position and angle for the arrow showing the process B -> A
    // Position is set to the midpoint on the curve (at parameter t=0.5)
    const arrow1Pos = {
        x: 0.25 * pointA.x + 0.5 * controlPoint1.x + 0.25 * pointB.x,
        y: 0.25 * pointA.y + 0.5 * controlPoint1.y + 0.25 * pointB.y
    };
    // The angle is calculated for the direction from point B to point A.
    const angle1 = Math.atan2(pointA.y - pointB.y, pointA.x - pointB.x);
    drawArrowhead(arrow1Pos.x, arrow1Pos.y, angle1, 15);

    // Add labels for points A and B
    ctx.fillText('A', pointA.x - 5, pointA.y - 20);
    ctx.fillText('B', pointB.x + 20, pointB.y);

    // --- Bottom Curve (Process C -> D) ---
    // Point D has lower volume and higher pressure than point C.
    const pointD = { x: 180, y: 260 };
    const pointC = { x: 360, y: 300 };
    // Control point for the second curve, also to create a concave-up shape.
    const controlPoint2 = {
        x: (pointD.x + pointC.x) / 2,
        y: (pointD.y + pointC.y) / 2 - 25
    };
    
    // Draw the second curve path
    ctx.beginPath();
    ctx.moveTo(pointD.x, pointD.y);
    ctx.quadraticCurveTo(controlPoint2.x, controlPoint2.y, pointC.x, pointC.y);
    ctx.stroke();

    // Calculate position and angle for the arrow showing the process C -> D
    const arrow2Pos = {
        x: 0.25 * pointD.x + 0.5 * controlPoint2.x + 0.25 * pointC.x,
        y: 0.25 * pointD.y + 0.5 * controlPoint2.y + 0.25 * pointC.y
    };
    // The angle is calculated for the direction from point C to point D.
    const angle2 = Math.atan2(pointD.y - pointC.y, pointD.x - pointC.x);
    drawArrowhead(arrow2Pos.x, arrow2Pos.y, angle2, 15);

    // Add labels for points C and D
    ctx.fillText('D', pointD.x - 5, pointD.y - 20);
    ctx.fillText('C', pointC.x + 20, pointC.y);

</script>
</body>
</html>